aboutsummaryrefslogtreecommitdiff
path: root/pages/anime/[...id].js
diff options
context:
space:
mode:
authorFactiven <[email protected]>2023-04-24 14:48:02 +0700
committerFactiven <[email protected]>2023-04-24 14:48:02 +0700
commit1211aeba0b1ca75ac1d6d5be0e8234541d52ae63 (patch)
tree00214cb44e0ec7633e68fd6980f1eb4d7cbc6746 /pages/anime/[...id].js
parentTemporary Fix (Manga) (diff)
downloadmoopa-1211aeba0b1ca75ac1d6d5be0e8234541d52ae63.tar.xz
moopa-1211aeba0b1ca75ac1d6d5be0e8234541d52ae63.zip
initial commit on pre-dev
Diffstat (limited to 'pages/anime/[...id].js')
-rw-r--r--pages/anime/[...id].js925
1 files changed, 408 insertions, 517 deletions
diff --git a/pages/anime/[...id].js b/pages/anime/[...id].js
index f58673d..cea025c 100644
--- a/pages/anime/[...id].js
+++ b/pages/anime/[...id].js
@@ -1,280 +1,359 @@
-import React, { useEffect, useState } from "react";
-import { META } from "@consumet/extensions";
+import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
+import "react-loading-skeleton/dist/skeleton.css";
-import Link from "next/link";
-import Layout from "../../components/layout";
import Head from "next/head";
-
-import { closestMatch } from "closest-match";
+import Image from "next/image";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import Layout from "../../components/layout";
+import Link from "next/link";
import Content from "../../components/hero/content";
-import { getServerSession } from "next-auth/next";
-import { authOptions } from "../api/auth/[...nextauth]";
-import Image from "next/image";
+import { useSession } from "next-auth/react";
-export default function Himitsu({
- info,
- color,
- episodeList,
- episode1,
- sessions,
- progress,
- status,
- lastPlayed,
- stall,
-}) {
- const [showText, setShowtext] = useState(false);
- const [load, setLoad] = useState(true);
- const [showAll, setShowAll] = useState(false);
- const [time, setTime] = useState(0);
+const query = `
+ query ($username: String, $status: MediaListStatus) {
+ MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) {
+ user {
+ id
+ name
+ about (asHtml: true)
+ createdAt
+ avatar {
+ large
+ }
+ statistics {
+ anime {
+ count
+ episodesWatched
+ meanScore
+ minutesWatched
+ }
+ }
+ bannerImage
+ mediaListOptions {
+ animeList {
+ sectionOrder
+ }
+ }
+ }
+ lists {
+ status
+ name
+ entries {
+ id
+ mediaId
+ status
+ progress
+ score
+ media {
+ id
+ status
+ title {
+ english
+ romaji
+ }
+ episodes
+ coverImage {
+ large
+ }
+ }
+ }
+ }
+ }
+ }
+ `;
+
+export default function Info() {
+ const { data: session, status } = useSession();
+ const [data, setData] = useState(null);
+ const [episode, setEpisode] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [progress, setProgress] = useState(null);
+ const [statuses, setStatuses] = useState(null);
+ const [stall, setStall] = useState(false);
+ const [color, setColor] = useState(null);
- const episode = episodeList;
- const epi1 = episode1;
+ const [showAll, setShowAll] = useState(false);
- const maxItems = 3;
+ const [time, setTime] = useState(0);
+ const { id } = useRouter().query;
- const nextAir = info.nextAiringEpisode;
- // console.log(time);
+ // console.log(stall);
useEffect(() => {
- if (nextAir) {
- setTime(convertSecondsToTime(nextAir.timeUntilAiring));
- }
-
- function getBrightness(color) {
- const rgb = color.match(/\d+/g);
- return (299 * rgb[0] + 587 * rgb[1] + 114 * rgb[2]) / 1000;
- }
+ const defaultState = {
+ data: null,
+ episode: null,
+ loading: true,
+ statuses: null,
+ progress: null,
+ };
- // set the text color based on the background color
- function setTextColor(element) {
- const backgroundColor = getComputedStyle(element).backgroundColor;
- const brightness = getBrightness(backgroundColor);
- if (brightness < 128) {
- element.style.color = "#fff"; // white
+ // Reset all state variables to their default values
+ Object.keys(defaultState).forEach((key) => {
+ const value = defaultState[key];
+ if (Array.isArray(value)) {
+ value.length
+ ? eval(
+ `set${
+ key.charAt(0).toUpperCase() + key.slice(1)
+ }(${JSON.stringify(value)})`
+ )
+ : eval(`set${key.charAt(0).toUpperCase() + key.slice(1)}([])`);
} else {
- element.style.color = "#000"; // black
+ eval(
+ `set${key.charAt(0).toUpperCase() + key.slice(1)}(${JSON.stringify(
+ value
+ )})`
+ );
}
- }
-
- const elements = document.querySelectorAll(".dynamic-text");
- elements.forEach((element) => {
- setTextColor(element);
});
+ async function fetchData() {
+ if (id) {
+ setLoading(false);
+ try {
+ const res = await fetch(
+ `https://api.moopa.my.id/meta/anilist/info/${id?.[0]}`
+ );
+ const data = await res.json();
+ if (data.episodes.length === 0) {
+ const res = await fetch(
+ `https://api.consumet.org/meta/anilist/info/${id[0]}?provider=9anime`
+ );
+ const datas = await res.json();
+ setColor({ backgroundColor: `${data?.color || "white"}` });
+ setStall(true);
+ setEpisode(datas.episodes);
+ } else {
+ setEpisode(data.episodes);
+ }
+
+ setColor({ backgroundColor: `${data?.color || "white"}` });
+
+ if (session?.user?.name) {
+ const response = await fetch("https://graphql.anilist.co/", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ query: query,
+ variables: {
+ username: session?.user?.name,
+ },
+ }),
+ });
+
+ const dat = await response.json();
+
+ const prog = dat.data.MediaListCollection;
+
+ const gat = prog.lists.map((item) => item.entries);
+ const git = gat.map((item) =>
+ item.find((item) => item.media.id === parseInt(data?.id))
+ );
+ const gut = git?.find(
+ (item) => item?.media.id === parseInt(data?.id)
+ );
+
+ if (gut) {
+ setProgress(gut?.progress);
+ if (gut.status === "CURRENT") {
+ setStatuses("Watching");
+ } else if (gut.status === "PLANNING") {
+ setStatuses("Planned to watch");
+ } else if (gut.status === "COMPLETED") {
+ setStatuses("Completed");
+ } else if (gut.status === "DROPPED") {
+ setStatuses("Dropped");
+ } else if (gut.status === "PAUSED") {
+ setStatuses("Paused");
+ } else if (gut.status === "REPEATING") {
+ setStatuses("Rewatching");
+ }
+ }
+ }
+
+ if (data.nextAiringEpisode) {
+ setTime(
+ convertSecondsToTime(data.nextAiringEpisode.timeUntilAiring)
+ );
+ }
- setLoad(false);
- }, [color, sessions, info.id]);
+ function getBrightness(color) {
+ const rgb = color.match(/\d+/g);
+ return (299 * rgb[0] + 587 * rgb[1] + 114 * rgb[2]) / 1000;
+ }
+ // set the text color based on the background color
+ function setTextColor(element) {
+ const backgroundColor = getComputedStyle(element).backgroundColor;
+ const brightness = getBrightness(backgroundColor);
+ if (brightness < 128) {
+ element.style.color = "#fff"; // white
+ } else {
+ element.style.color = "#000"; // black
+ }
+ }
+
+ const elements = document.querySelectorAll(".dynamic-text");
+ elements.forEach((element) => {
+ setTextColor(element);
+ });
+
+ setData(data);
+ setLoading(true);
+ } catch (error) {
+ setTimeout(() => {
+ window.location.reload();
+ }, 1000);
+ }
+ }
+ // setLoading(true);
+ }
+ fetchData();
+ }, [id, session?.user?.name]);
+ // console.log(episode);
return (
<>
<Head>
- <title>{info.title?.english || info.title.romaji}</title>
- <meta name="detail" content="Detail about the Anime" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <link rel="icon" href="/c.svg" />
+ <title>{data?.title?.romaji || data?.title?.english}</title>
</Head>
-
- <Layout navTop="text-white bg-primary md:pt-0 md:px-0 bg-slate bg-opacity-40">
- <div className="text static bg-primary flex w-screen flex-col justify-center pt-nav md:pt-1 pb-10">
- <div className="pointer-events-none absolute top-0 left-0">
- <div className="absolute bg-gradient-to-t w-screen z-20 top-0 md:h-[300px] h-[420px] from-10% from-primary to-transparent" />
- <img
- // ref={ref}
- src={info.cover || info.image}
- className="md:h-[300px] h-[420px] w-screen object-cover brightness-[60%]"
- />
- </div>
- {info ? (
- <div className="flex flex-col items-center gap-10">
- <div className="flex w-screen flex-col gap-10 md:w-[70%]">
- <div className="z-40 flex flex-col gap-10 px-5 pt-[7rem] md:flex-row lg:mt-[5rem] lg:px-0">
- <div className="flex gap-5 md:h-[250px] md:w-52">
- <div className="flex h-[200px] w-52 bg-[#dadada50] md:h-[250px] md:w-full">
- {info.image && (
- <>
- <div
- key={info.id}
- // src={info.image}
- className=""
- >
- <Image
- src={info.image}
- alt="image"
- width={500}
- height={500}
- draggable={false}
- className="object-cover h-[200px] w-[200px] md:h-[250px] shrink-0 bg-image shadow-md"
- />
- </div>
- </>
+ <SkeletonTheme baseColor="#3B3C41" highlightColor="#4D4E52">
+ <Layout navTop="text-white bg-primary md:pt-0 md:px-0 bg-slate bg-opacity-40 z-50">
+ <div className="w-screen min-h-screen relative flex flex-col items-center bg-primary gap-5">
+ <div className="bg-image">
+ <div className="bg-gradient-to-t from-primary from-10% to-transparent absolute h-[300px] w-screen z-10 inset-0" />
+ {data && (
+ <Image
+ src={data?.cover}
+ alt="banner anime"
+ height={1000}
+ width={1000}
+ className="object-cover bg-image w-screen absolute top-0 left-0 h-[300px] brightness-75 z-0"
+ />
+ )}
+ </div>
+ <div className="lg:w-[70%] pt-[10rem] z-30 flex flex-col gap-10">
+ <div className="md:flex gap-5 w-full flex-nowrap">
+ <div className="shrink-0 md:h-[250px] md:w-[180px] w-[115px] h-[164px] relative">
+ {loading ? (
+ data && (
+ <>
+ <div className="bg-image md:h-[250px] md:w-[180px] w-[115px] h-[164px] bg-opacity-30 absolute backdrop-blur-lg z-10" />
+ <Image
+ src={data.image}
+ alt="poster anime"
+ height={700}
+ width={700}
+ className="object-cover md:h-[250px] md:w-[180px] w-[115px] h-[164px] z-20 absolute"
+ />
+ </>
+ )
+ ) : (
+ <Skeleton className="h-[250px] w-[180px]" />
+ )}
+ </div>
+ <div className="flex w-full flex-col gap-10 h-[250px]">
+ <div className="flex flex-col gap-2">
+ <h1 className=" font-inter font-bold text-[36px] text-white line-clamp-1">
+ {loading ? (
+ data?.title?.romaji || data?.title?.english
+ ) : (
+ <Skeleton width={450} />
)}
- </div>
-
- {/* MOBILE */}
- <div className="w-full grid place-items-stretch gap-3 lg:hidden ">
- <h1 className="shrink-0 text-xl font-semibold line-clamp-2">
- {info.title.romaji || info.title.english}
- </h1>
- <div className="flex w-[90%] flex-col gap-1">
- <div className="flex gap-2">
- <h1>Rate:</h1>
- <p className="font-bold">{info.rating}%</p>
- </div>
-
- <div className="flex w-[200px] gap-2">
- <h1>Format:</h1>
- <p>{info.type}</p>
- </div>
-
- <div className="flex gap-2">
- <h1>Status:</h1>
- <p>{info.status}</p>
- </div>
-
- {/* {nextAir && (
- <div className="flex gap-2">
- <h1>Ep {nextAir.episode}:</h1>
- <p>{time}</p>
- </div>
- )} */}
- </div>
- <div className="flex">
- {epi1 && epi1[0] ? (
- <Link href={`/anime/watch/${epi1[0].id}/${info.id}`}>
- <h1 className="flex cursor-pointer items-center gap-2 px-1 py-2 font-bold text-[#ffffff]">
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="13"
- height="12"
- fill="none"
- viewBox="0 0 250 289"
- >
- <path
- fill="#fff"
- d="M249.734 144.5l-249 143.761V.741l249 143.759z"
- ></path>
- </svg>{" "}
- WATCH
- </h1>
- </Link>
- ) : (
- <h1 className="pointer-events-none flex items-center gap-2 px-1 py-2 font-bold text-[#ffffffa5]">
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="13"
- height="12"
- className="fill-[#ffffff8d]"
- viewBox="0 0 250 289"
+ </h1>
+ {loading ? (
+ data && (
+ <div>
+ <div className="flex gap-6">
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
>
- <path d="M249.734 144.5l-249 143.761V.741l249 143.759z"></path>
- </svg>{" "}
- WATCH
- </h1>
- )}
- </div>
- </div>
- </div>
-
- {/* PC */}
- <div className="w-full flex-col gap-5 md:flex">
- <div className="hidden flex-col gap-5 lg:flex">
- <h1 className="text-4xl font-bold">
- {info.title?.english ||
- info.title.romaji ||
- info.title.native}
- </h1>
- <div className="flex gap-6">
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- {episode && episode.length} Episodes
- </div>
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- {info.releaseDate}
- </div>
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- {info.rating}%
- </div>
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- {info.type}
- </div>
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- {info.status}
- </div>
- <div
- className={`dynamic-text rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- Sub | EN
- </div>
- {nextAir && (
- <div
- className={`dynamic-text shadow-button rounded-md px-2 font-karla font-bold`}
- style={color}
- >
- Ep {nextAir.episode}: {time}
+ {data?.totalEpisodes} Episodes
+ </div>
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ {data?.releaseDate}
+ </div>
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ {data?.rating}%
+ </div>
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ {data?.type}
+ </div>
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ {data?.status}
+ </div>
+ <div
+ className={`dynamic-text text-black rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ Sub | EN
+ </div>
+ {data && data.nextAiringEpisode && (
+ <div
+ className={`dynamic-text text-black shadow-button rounded-md px-2 font-karla font-bold`}
+ style={color}
+ >
+ Ep {data.nextAiringEpisode.episode}: {time}
+ </div>
+ )}
</div>
- )}
- </div>
- </div>
- <div
- className={`hidden h-[140px] transition-all duration-300 scrollbar-thin scrollbar-thumb-[#1b1c21] scrollbar-thumb-rounded-md overflow-y-scroll hover:scrollbar-thumb-[#2e2f37] lg:block`}
- >
- <p
- dangerouslySetInnerHTML={{ __html: info.description }}
- className="mr-5"
- />
- </div>
- <div className="lg:hidden text-sm text-txt">
- <p
- className={`${showText ? "" : "line-clamp-3"}`}
- dangerouslySetInnerHTML={{
- __html: info.description,
- }}
- />
- <button
- onClick={() => setShowtext(!showText)}
- className="font-rama font-bold text-white"
- >
- {showText ? " Show Less" : " Show More"}
- </button>
- </div>
+ </div>
+ )
+ ) : (
+ <Skeleton width={240} height={32} />
+ )}
</div>
+ {loading ? (
+ <p
+ dangerouslySetInnerHTML={{ __html: data?.description }}
+ className="overflow-y-scroll scrollbar-thin pr-2 scrollbar-thumb-secondary scrollbar-thumb-rounded-lg h-[125px]"
+ />
+ ) : (
+ <Skeleton className="h-[110px]" />
+ )}
+ {/* <p>{data.description}</p> */}
</div>
+ </div>
- <div className="">
- <div className="flex gap-5 items-center">
+ <div>
+ <div className="flex gap-5 items-center">
+ {data && (
<div className="p-3 lg:p-0 text-[20px] md:text-2xl font-bold font-karla">
Relations
</div>
- {info.relations.length > maxItems && (
- <div
- className="cursor-pointer"
- onClick={() => setShowAll(!showAll)}
- >
- {showAll ? "show less" : "show more"}
- </div>
- )}
- </div>
- <div
- className={`w-screen lg:w-full grid lg:grid-cols-3 justify-items-center gap-7 lg:pt-7 px-3 lg:px-4 pt-10 rounded-xl`}
- >
- {info.relations &&
- info.relations
- .slice(0, showAll ? info.relations.length : maxItems)
+ )}
+ {data?.relations?.length > 3 && (
+ <div
+ className="cursor-pointer"
+ onClick={() => setShowAll(!showAll)}
+ >
+ {showAll ? "show less" : "show more"}
+ </div>
+ )}
+ </div>
+ <div
+ className={`w-screen lg:w-full grid lg:grid-cols-3 justify-items-center gap-7 lg:pt-7 px-3 lg:px-4 pt-10 rounded-xl`}
+ >
+ {loading
+ ? data?.relations &&
+ data?.relations
+ .slice(0, showAll ? data?.relations.length : 3)
.map((relation, index) => {
return (
<Link
@@ -289,9 +368,9 @@ export default function Himitsu({
: `/manga/detail/id?aniId=${
relation.id
}&aniTitle=${encodeURIComponent(
- info.title?.english ||
- info.title.romaji ||
- info.title.native
+ data?.title?.english ||
+ data?.title.romaji ||
+ data?.title.native
)}`
}
className={`hover:scale-[1.02] hover:shadow-lg md:px-0 px-4 scale-100 transition-transform duration-200 ease-out w-full ${
@@ -305,9 +384,11 @@ export default function Himitsu({
className="w-full shrink h-[126px] bg-secondary flex rounded-md"
>
<div className="w-[90px] bg-image rounded-l-md shrink-0">
- <img
+ <Image
src={relation.image}
alt={relation.id}
+ height={500}
+ width={500}
className="object-cover h-full w-full shrink-0 rounded-l-md"
/>
</div>
@@ -323,287 +404,97 @@ export default function Himitsu({
</div>
</Link>
);
- })}
- </div>
+ })
+ : [1, 2, 3].map((item) => (
+ <div key={item} className="w-full">
+ <Skeleton className="h-[126px]" />
+ </div>
+ ))}
</div>
-
- <div className="z-20 flex flex-col gap-10 p-3 lg:p-0">
- <div className="flex items-center md:gap-10 gap-7">
+ </div>
+ <div className="z-20 flex flex-col gap-10 p-3 lg:p-0">
+ <div className="flex items-center md:gap-10 gap-7">
+ {data && (
<h1 className="text-[20px] md:text-2xl font-bold font-karla">
Episodes
</h1>
- <div className="flex items-center rounded-md">
- <button
- // onClick={handleEnLang}
- className={
- // Lang?
- `w-14 p-1 rounded-l-md bg-secondary text-action shadow-action`
- // `w-14 p-1 rounded-l-md bg-[#17171b] text-[#404040]`
- }
- >
- EN
- </button>
- <div className="w-[1px] bg-white h-4" />
- <button
- // onClick={handleIdLang}
- className={
- // subIndo === null
- // ?
- `w-14 p-1 rounded-r-md bg-[#171717] text-[#404040] pointer-events-none`
- // : Lang
- // ? `w-14 p-1 rounded-r-md bg-[#171717] text-[#404040]`
- // : `w-14 p-1 rounded-r-md bg-[#212121]`
- }
- >
- ID
- </button>
- </div>
- {status && (
- <>
- <div className="font-karla relative group flex justify-center">
- {status}
- <span className="absolute bottom-8 shadow-lg invisible group-hover:visible transition-all opacity-0 group-hover:opacity-100 font-karla font-light bg-secondary p-1 px-2 rounded-lg">
- status
- </span>
- </div>
- </>
- )}
- </div>
- <div className="flex h-[640px] flex-col gap-5 scrollbar-thin scrollbar-thumb-[#1b1c21] scrollbar-thumb-rounded-full overflow-y-scroll hover:scrollbar-thumb-[#2e2f37]">
- {load ? (
- <p>Loading...</p>
- ) : episode ? (
- episode.map((episode, index) => {
- return (
- <div key={index} className="flex flex-col gap-3 px-2">
- <Link
- href={`/anime/watch/${episode.id}/${info.id}/${
- stall ? `9anime` : ""
- }`}
- className={`text-start text-sm md:text-lg ${
- episode.number <= progress
- ? "text-[#5f5f5f]"
- : "text-white"
- }`}
- >
- <p>Episode {episode.number}</p>
- {episode.title && (
- <p
- className={`text-xs md:text-sm ${
- episode.number <= progress
- ? "text-[#5f5f5f]"
- : "text-[#b1b1b1]"
- } italic`}
- >
- "{episode.title}"
- </p>
- )}
- </Link>
- <div className="h-[1px] bg-white" />
- </div>
- );
- })
- ) : (
- <p>No Episodes Available</p>
- )}
- </div>
+ )}
+ {statuses && (
+ <>
+ <div className="font-karla relative group flex justify-center">
+ {statuses}
+ <span className="absolute bottom-8 shadow-lg invisible group-hover:visible transition-all opacity-0 group-hover:opacity-100 font-karla font-light bg-secondary p-1 px-2 rounded-lg">
+ status
+ </span>
+ </div>
+ </>
+ )}
</div>
+ {loading ? (
+ data && (
+ <div className="flex h-[640px] flex-col gap-5 scrollbar-thin scrollbar-thumb-[#1b1c21] scrollbar-thumb-rounded-full overflow-y-scroll hover:scrollbar-thumb-[#2e2f37]">
+ {episode ? (
+ episode.map((episode, index) => {
+ return (
+ <div
+ key={index}
+ className="flex flex-col gap-3 px-2"
+ >
+ <Link
+ href={`/anime/watch/${episode.id}/${data.id}/${
+ stall ? `9anime` : ""
+ }`}
+ className={`text-start text-sm md:text-lg ${
+ episode.number <= progress
+ ? "text-[#5f5f5f]"
+ : "text-white"
+ }`}
+ >
+ <p>Episode {episode.number}</p>
+ {episode.title && (
+ <p
+ className={`text-xs md:text-sm ${
+ episode.number <= progress
+ ? "text-[#5f5f5f]"
+ : "text-[#b1b1b1]"
+ } italic`}
+ >
+ "{episode.title}"
+ </p>
+ )}
+ </Link>
+ <div className="h-[1px] bg-white" />
+ </div>
+ );
+ })
+ ) : (
+ <p>No Episodes Available</p>
+ )}
+ </div>
+ )
+ ) : (
+ <></>
+ )}
</div>
+ </div>
+ {data && (
<div className="w-screen md:w-[80%]">
<Content
ids="recommendAnime"
section="Recommendations"
- data={info.recommendations}
+ data={data.recommendations}
/>
</div>
- </div>
- ) : (
- <div className="flex h-screen flex-col items-center justify-center gap-10 pb-52 ">
- <h1 className="scale-150 font-roboto text-6xl text-red-400">
- 404
- </h1>
- <p className="text-4xl font-semibold">{`> Woops.. I think we don't have that Anime :(`}</p>
- <Link className="pt-10 text-2xl" href="/search/anime">
- Return to search
- </Link>
- </div>
- )}
- </div>
- </Layout>
+ )}
+ <div></div>
+ <div></div>
+ </div>
+ </Layout>
+ </SkeletonTheme>
</>
);
}
-export async function getServerSideProps(context) {
- context.res.setHeader(
- "Cache-Control",
- "public, s-maxage=10, stale-while-revalidate=59"
- );
- const session = await getServerSession(context.req, context.res, authOptions);
-
- const { id } = context.query;
- if (!id) {
- return {
- notFound: true,
- };
- }
-
- const provider = new META.Anilist();
-
- const [info, episodes] = await Promise.all([
- fetch(`https://api.moopa.my.id/meta/anilist/info/${id[0]}`).then((res) =>
- res.json()
- ),
- provider.fetchEpisodesListById(id[0]),
- ]);
-
- if (!info) {
- return {
- notFound: true,
- };
- }
-
- let episodeList = episodes;
- let stall = false;
-
- if (episodes.length === 0) {
- const res = await fetch(
- `https://api.consumet.org/meta/anilist/info/${id[0]}?provider=9anime`
- );
- const data = await res.json();
- episodeList = data.episodes;
- stall = true;
- }
-
- let progress = null;
- let status = null;
- let lastPlayed = null;
-
- if (session) {
- const response = await fetch("https://graphql.anilist.co/", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- query: `
- query ($username: String, $status: MediaListStatus) {
- MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) {
- user {
- id
- name
- about (asHtml: true)
- createdAt
- avatar {
- large
- }
- statistics {
- anime {
- count
- episodesWatched
- meanScore
- minutesWatched
- }
- }
- bannerImage
- mediaListOptions {
- animeList {
- sectionOrder
- }
- }
- }
- lists {
- status
- name
- entries {
- id
- mediaId
- status
- progress
- score
- media {
- id
- status
- title {
- english
- romaji
- }
- episodes
- coverImage {
- large
- }
- }
- }
- }
- }
- }
- `,
- variables: {
- username: session?.user.name,
- },
- }),
- });
-
- const dat = await response.json();
-
- // const resp = await fetch(`/api/get-user?userName=${session?.user.name}`);
- // const data = await resp.json();
-
- lastPlayed = session?.user?.recentWatch?.filter(
- (item) => item.title.romaji === info.title.romaji
- )[0]?.episode;
-
- const prog = dat.data.MediaListCollection;
-
- const gat = prog.lists.map((item) => item.entries);
- const git = gat.map((item) =>
- item.find((item) => item.media.id === parseInt(info.id))
- );
- const gut = git?.find((item) => item?.media.id === parseInt(info.id));
-
- if (gut) {
- progress = gut?.progress;
- if (gut.status === "CURRENT") {
- status = "Watching";
- } else if (gut.status === "PLANNING") {
- status = "Planned to watch";
- } else if (gut.status === "COMPLETED") {
- status = "Completed";
- } else if (gut.status === "DROPPED") {
- status = "Dropped";
- } else if (gut.status === "PAUSED") {
- status = "Paused";
- } else if (gut.status === "REPEATING") {
- status = "Rewatching";
- }
- }
- }
-
- const color = { backgroundColor: `${info.color}` };
- const epi1 = episodes.filter((epi) => epi.number === 1);
- const title = info.title?.userPreferred || "No Title";
-
- return {
- props: {
- info: {
- ...info,
- title: {
- ...info.title,
- userPreferred: title,
- },
- },
- color,
- episodeList,
- episode1: epi1,
- sessions: session,
- progress: progress || null,
- status: status,
- lastPlayed: lastPlayed || null,
- stall,
- },
- };
-}
-
function convertSecondsToTime(sec) {
let days = Math.floor(sec / (3600 * 24));
let hours = Math.floor((sec % (3600 * 24)) / 3600);